<?php
/**
 * Created by PhpStorm.
 * User: rocky
 * Date: 2019-07-14
 * Time: 10:49
 */

namespace app\api\service;


use app\common\facade\Token;
use app\common\model\User;
use app\wechat\service\WechatService as Wechat;
use library\File;
use library\tools\Data;
use think\facade\Cache;
use think\facade\Session;
use WeChat\Contracts\Tools;

class WechatService
{
    //微信授权登陆，返回user模型
    public static function auth()
    {
        $appid = Wechat::getAppid();
        $sessionkey = "{$appid}_fansinfo";
        if (Session::has($sessionkey)) {
            $fansinfo = session($sessionkey);
            if (!isset($fansinfo['unionid'])) {
                $fansinfo['unionid'] = '';
            }
            $user = User::where('openid', $fansinfo['openid'])->whereOr(function ($q) use ($fansinfo) {
                $q->where('unionid', $fansinfo['unionid'])->whereNotNull('unionid')->where('unionid', '<>', '');
            })->find();
            if ($user) {
                $user->nickname = $fansinfo['nickname'];
                $user->headimg = $fansinfo['headimgurl'];
                $user->openid = $fansinfo['openid'];
                $user->unionid = $fansinfo['unionid'];
                $user->save();
            } else {
                $user = User::create([
                    'nickname' => $fansinfo['nickname'],
                    'headimg' => $fansinfo['headimgurl'],
                    'openid' => $fansinfo['openid'],
                    'unionid' => $fansinfo['unionid'],
                    'country' => $fansinfo['country'],
                    'city' => $fansinfo['city'],
                    'province' => $fansinfo['province'],
                ]);
            }
        } else {
            Wechat::getWebOauthInfo(request()->url(true), 1);
        }
        return $user;
    }
    /**
     * 微信支付
     * @Author: rocky
     * 2019/7/22 15:33
     * @param $openid openid
     * @param $title 下单标题
     * @param $order_sn 订单号
     * @param $total  总价
     * @param $notify_url  回调地址
     * @return mixed
     */
    public static function pay($openid, $title, $order_sn, $total, $notify_url)
    {
        $wechatPay = Wechat::WePayOrder();
        $res = $wechatPay->create([
            'body' => $title,
            'out_trade_no' => $order_sn,
            'total_fee' => $total * 100,
            'spbill_create_ip' => request()->ip(),
            'notify_url' => $notify_url,
            'trade_type' => 'JSAPI',
            'openid' => $openid,
        ]);
        $wechatPayConfig = $wechatPay->jsapiParams($res['prepay_id']);
        return $wechatPayConfig;
    }

    /**
     * 微信申请退款
     * @Author: rocky
     * 2019/9/2 11:11
     * @param $transaction_id 微信订单号
     * @param $order_sn 订单号
     * @param $total_fee 订单金额
     * @param $refund_fee 退款金额
     * @return bool
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     */
    public static function refund($transaction_id, $order_sn, $total_fee, $refund_fee)
    {
        $options = [
            'transaction_id' => $transaction_id,
            'out_refund_no' => $order_sn,
            'total_fee' => $total_fee * 100,
            'refund_fee' => $refund_fee * 100,
        ];

        $res = Wechat::WePayRefund()->create($options);
        if ($res['result_code'] == 'SUCCESS') {
            return true;
        } else {
            return $res['err_code_des'];
        }
    }

    /**
     * 微信企业付款
     * @Author: rocky
     * 2019/9/2 11:01
     * @param $openid openid
     * @param $money 打款金额
     * @param $desc 打款描述
     * @return bool
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     */
    public static function transfersPay($openid, $money, $desc)
    {
        $options = [
            'partner_trade_no' => time(),
            'openid' => $openid,
            'check_name' => 'NO_CHECK',
            'amount' => $money * 100,
            'desc' => $desc,
            'spbill_create_ip' => request()->ip(),
        ];
        $result = Wechat::WePayTransfers()->create($options);
        if ($result['result_code'] == 'SUCCESS') {
            return true;
        } else {
            return $result['err_code_des'];
        }
    }

    /**
     * serverId保存微信图片返回url
     * @Author: rocky
     * 2019/12/21 14:17
     * @param $serverId 素材id
     * @return mixed
     */
    public static function getWechatImg($serverId)
    {
        $content = Wechat::WeChatMedia()->get($serverId);
        $filename = 'wechat/' . Data::randomCode(30, 3) . '.png';
        $res = File::save($filename, $content);
        return $res['url'];
    }

    /**
     * 获取授权code 跳转地址
     * @Author: rocky
     * 2020/1/6 11:20
     * @param string $url 授权页面URL地址
     * @param integer $isfull 授权微信模式
     * @return string 返回授权code 跳转地址
     */
    public static function getCodeTargetUrl($url, $isfull = 'snsapi_userinfo')
    {
        $wechat = Wechat::WeChatOauth();
        $param = (strpos($url, '?') !== false ? '&' : '?') . 'rcode=' . encode($url);
        $snsapi = empty($isfull) ? 'snsapi_base' : 'snsapi_userinfo';
        $OauthUrl = $wechat->getOauthRedirect($url . $param, Wechat::getAppid(), $snsapi);
        return $OauthUrl;
    }

    /**
     * 微信code登录返回token
     * @Author: rocky
     * 2020/1/6 11:28
     * @param $code 微信code
     * @return array
     */
    public static function codeLogin($code)
    {
        $_GET['code'] = $code;
        $wechat = Wechat::WeChatOauth();
        if (($token = $wechat->getOauthAccessToken()) && isset($token['openid'])) {
            $fansinfo = $wechat->getUserInfo($token['access_token'], $token['openid']);
            $user = User::where('openid', $fansinfo['openid'])->whereOr(function ($q) use ($fansinfo) {
                $q->where('unionid', $fansinfo['unionid'])->whereNotNull('unionid')->where('unionid', '<>', '');
            })->find();
            if ($user) {
                $user->nickname = $fansinfo['nickname'];
                $user->headimg = $fansinfo['headimgurl'];
                $user->openid = $fansinfo['openid'];
                $user->unionid = $fansinfo['unionid'];
                $user->save();
            } else {
                $user = User::create([
                    'nickname' => $fansinfo['nickname'],
                    'headimg' => $fansinfo['headimgurl'],
                    'openid' => $fansinfo['openid'],
                    'unionid' => $fansinfo['unionid'],
                    'country' => $fansinfo['country'],
                    'city' => $fansinfo['city'],
                    'province' => $fansinfo['province'],
                ]);
            }
            $tokenArr = Token::encode($user->getData());
            return $tokenArr;
        }
    }

    /**
     * 公众号发送模板消息
     * @Author: rocky
     * 2020/2/25 16:55
     * @param $template_id 模板id
     * @param $open_id 微信open_id
     * @param $content 发送内容  格式：标题1&标题1 或数组 ['标题1','标题2']
     * @param string $url 跳转地址 或 数组方式跳转小程序 ['appid'=>'234','pagepath'=>'pages/index/index']
     * @param string $color 文字颜色
     * @return array
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     */
    public static function sendTemplate($template_id, $open_id, $content, $url = '', $color = '#5d5d58')
    {
        if (is_array($content)) {
            foreach ($content as $key => $value) {
                $data['keyword' . ($key + 1)]['value'] = $value;
                $data['keyword' . ($key + 1)]['color'] = $color;
            }
        } else {
            foreach (explode('&', $content) as $key => $value) {
                $data['keyword' . ($key + 1)]['value'] = $value;
                $data['keyword' . ($key + 1)]['color'] = $color;
            }
        }
        $postData = [
            'touser' => $open_id,
            'template_id' => $template_id,
            'data' => $data,
        ];
        if ($url) {
            if (is_array($url)) {
                $postData['miniprogram'] = $url;
            } else {
                $postData['url'] = $url;
            }
        }
        $result = Wechat::WeChatTemplate()->send($postData);
        return $result;
    }

    /**
     * 生成一次性订阅模板消息请求链接
     * @Author: rocky
     * 2019/12/23 15:05
     * @param $template_id 模板消息id
     * @param $scene 场景
     * @param string $redirect_url 跳转链接
     * @return string
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function subscribeMsgUrl($template_id, $scene, $redirect_url = '')
    {
        $url = 'https://mp.weixin.qq.com/mp/subscribemsg';
        if (empty($redirect_url)) {
            $redirect_url = request()->url(true);
        }
        $reserved = Data::randomCode(10, 3);
        $data = [
            'action' => 'get_confirm',
            'appid' => Wechat::getAppid(),
            'scene' => $scene,
            'template_id' => $template_id,
            'redirect_url' => $redirect_url,
            'reserved' => $reserved
        ];
        Cache::set('subscribeMsg_reserved_' . \app\common\facade\Token::id(), $reserved);
        return $url . '?' . http_build_query($data) . '#wechat_redirect';
    }

    /**
     * 一次性订阅模板消息发送
     * @Author: rocky
     * 2019/12/23 14:43
     * @param $template_id 订阅消息模板ID
     * @param $open_id 微信用户openid
     * @param $title 标题
     * @param $content 内容
     * @param $scene 场景值
     * @param $jumpType 跳转类型：1链接，2小程序
     * @param $jumpUrl 跳转路径
     * @param string $color 内容文字颜色
     * @return array
     */
    public static function templateSubscribe($template_id, $open_id, $title, $content, $scene, $jumpUrl = '', $jumpType = 1, $color = '#5d5d58')
    {
        $accessToken = Wechat::WeChatUser()->getAccessToken();
        $url = 'https://api.weixin.qq.com/cgi-bin/message/template/subscribe?access_token=' . $accessToken;
        $data = [
            'touser' => $open_id,
            'template_id' => $template_id,
            'title' => $title,
            'scene' => $scene,
            'data' => [
                'content' => [
                    'value' => $content,
                    'color' => $color
                ]
            ]
        ];
        if ($jumpType == 1) {
            if (!empty($jumpUrl)) {
                $data['url'] = $jumpUrl;
            }
        } else {
            if (!empty($jumpUrl)) {
                $data['miniprogram'] = [
                    'appid' => Wechat::getAppid(),
                    'pagepath' => $jumpUrl,
                ];
            }
        }
        $result = Tools::json2arr(Tools::post($url, Tools::arr2json($data)));
        return $result;
    }
}